#
#    Copyright (c) 2023 Project CHIP Authors
#
#    Licensed under the Apache License, Version 2.0 (the 'License');
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an 'AS IS' BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
import os
from typing import TextIO

from matter.yamltests.yaml_loader import SchemaTree, yaml_tree

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
WARNING = ("<!---\n"
           "This file is automatically generated by a script.\n"
           "DO NOT HAND-EDIT THIS FILE.\n"
           f"Script: {os.path.basename(__file__)}\n"
           "-->\n\n")


def get_type_list_and_vars(typetuple) -> (list[type], bool):
    "Returns a list of supported types for this type tuple and a bool indicating if variables are supported."
    # If str is one of the supported types, and other base types are supported,
    # this means it supports variables.
    # This is a heuristic, but it's true for now.
    try:
        typelist = list(typetuple)
        if str in typelist:
            # The tuple passed from the yaml parser is a tuple of type classes
            # Here, we directly compare to the base type because that's what
            # we get from the parser (ex. (bool, int, str))
            reduced = [t for t in typelist if t != str]
            if reduced != [list]:
                return (reduced, True)
        return (typelist, False)
    except TypeError:
        return ([typetuple], False)


def print_tree(f: TextIO, indent: str, tree: SchemaTree) -> None:
    for tag, typetuple in tree.schema.items():
        vars_str = ""
        typelist, vars = get_type_list_and_vars(typetuple)
        vars_str = "Y" if vars else ""
        typestr = ','.join([t.__name__ for t in typelist])

        try:
            child = tree.children[tag]
            f.writelines([f'|{indent}{tag} | |{vars_str} |\n'])
            print_tree(f, indent+'&emsp; ', child)
        except (TypeError, KeyError):
            f.writelines([f'|{indent}{tag} |{typestr}|{vars_str}|\n'])


def print_table(title: str, tree: SchemaTree) -> None:
    doc_path = os.path.abspath(os.path.join(
        SCRIPT_DIR, '..', '..', 'docs', 'testing', 'yaml_schema.md'))
    with open(doc_path, "w") as f:
        f.writelines(WARNING)
        f.writelines('# YAML Schema\n\n')
        f.writelines([f'{title}\n',
                      '|key | type| supports variables\n',
                      '|:---|:---|:---|\n'])
        print_tree(f, '', tree)


print_table('YAML schema', yaml_tree)
